package com.zzl.alligator.management.monitor.controller;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.system.HostInfo;
import cn.hutool.system.JvmInfo;
import cn.hutool.system.OsInfo;
import cn.hutool.system.RuntimeInfo;
import cn.hutool.system.SystemUtil;
import cn.hutool.system.oshi.CpuInfo;
import cn.hutool.system.oshi.OshiUtil;
import com.zzl.alligator.framework.base.controller.BaseController;
import com.zzl.alligator.framework.support.web.vo.JsonResult;
import com.zzl.alligator.management.monitor.domain.sysinfo.JvmRunInfo;
import com.zzl.alligator.management.monitor.domain.sysinfo.MemInfo;
import com.zzl.alligator.management.monitor.domain.sysinfo.SysFile;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import oshi.hardware.GlobalMemory;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统监控信息
 *
 * @author zhouziliang
 * @since 2020/7/9
 */
@RestController
@RequestMapping("/monitor/system")
public class SysInfoController extends BaseController {

    /**
     * 系统信息
     *
     * @return 系统信息
     */
    @PreAuthorize("@ss.hasPermi('monitor:server:list')")
    @GetMapping
    public JsonResult geiSysInfo() {
        CpuInfo cpuInfo = OshiUtil.getCpuInfo();
        GlobalMemory memory = OshiUtil.getHardware().getMemory();
        MemInfo memInfo = new MemInfo();
        memInfo.setTotal(memory.getTotal());
        memInfo.setFree(memory.getAvailable());
        memInfo.setUsed(memory.getTotal() - memory.getAvailable());
        OsInfo osInfo = SystemUtil.getOsInfo();
        RuntimeInfo runtimeInfo = SystemUtil.getRuntimeInfo();
        JvmRunInfo jvmRunInfo = new JvmRunInfo();
        jvmRunInfo.setTotal(runtimeInfo.getTotalMemory());
        jvmRunInfo.setFree(runtimeInfo.getFreeMemory());
        jvmRunInfo.setMax(runtimeInfo.getMaxMemory());
        JvmInfo jvmInfo = SystemUtil.getJvmInfo();
        HostInfo hostInfo = SystemUtil.getHostInfo();
        FileSystem fileSystem = OshiUtil.getOs().getFileSystem();
        List<OSFileStore> fileStores = fileSystem.getFileStores();
        List<SysFile> sysFiles = null;
        if (fileStores != null) {
            sysFiles = fileStores.stream().map(disk -> {
                SysFile sysFile = new SysFile();
                sysFile.setDirName(disk.getMount());
                sysFile.setTypeName(disk.getName());
                sysFile.setSysTypeName(disk.getType());
                long totalSpace = disk.getTotalSpace();
                long usableSpace = disk.getUsableSpace();
                sysFile.setTotal(convertFileSize(totalSpace));
                sysFile.setUsed(convertFileSize(totalSpace - usableSpace));
                sysFile.setFree(convertFileSize(usableSpace));
                sysFile.setUsage(NumberUtil.mul(NumberUtil.div(usableSpace, totalSpace), 100));
                return sysFile;
            }).collect(Collectors.toList());


        }
        Map<String, Object> map = new HashMap<>(7);

        map.put("cpu", cpuInfo);
        map.put("mem", memInfo);
        map.put("os", osInfo);
        map.put("jvm", jvmInfo);
        map.put("runtime", jvmRunInfo);
        map.put("host", hostInfo);
        map.put("sysFiles", sysFiles);
        return JsonResult.success(map);
    }


    /**
     * 字节转换
     *
     * @param size 字节大小
     * @return 转换后值
     */
    public String convertFileSize(long size) {
        long kb = 1024;
        long mb = kb * 1024;
        long gb = mb * 1024;
        if (size >= gb) {
            return String.format("%.1f GB", (float) size / gb);
        } else if (size >= mb) {
            float f = (float) size / mb;
            return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
        } else if (size >= kb) {
            float f = (float) size / kb;
            return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
        } else {
            return String.format("%d B", size);
        }
    }
}
